package com.qq.BFMRSE.BF_MRSEController;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.qq.BFMRSE.Cache.indexCacheManager;
import com.qq.BFMRSE.Hdfs.hdfsOper;
import com.qq.BFMRSE.controllerHelper.searchHelper;
import com.qq.BFMRSE.model.encryptedIndex;
import com.qq.BFMRSE.model.fileScorePair;
import com.qq.BFMRSE.model.indexTree;
import com.qq.BFMRSE.model.indexTreeNode;
import com.qq.BFMRSE.model.trapDoor;
import com.qq.BFMRSE.model.user;
import com.qq.BFMRSE.util.BFConstants;
import com.qq.BFMRSE.util.paraseJsonUtil;

import net.sf.json.JSONArray;

@Controller
public class handlerSearch {
	@RequestMapping(value= "/search",method=RequestMethod.POST)
	public void handler(HttpServletRequest request,HttpServletResponse response){
    	WebApplicationContext wac=WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
    	indexCacheManager cacheInstance=(indexCacheManager) wac.getBean("cacheInstance");//索引缓存
		 response.setContentType("text/html;charset=utf-8");
	     response.setCharacterEncoding("utf-8");
	     Logger log=Logger.getLogger(handlerSearch.class);
	     String searchTrapDoor=request.getParameter("searchTrapDoor");
	     String trapBitsInfo=request.getParameter("trapBitsInfo");
	     String userName=request.getParameter("userName");
	     String inputK=request.getParameter("K");
	     int k=5;
	     if(inputK!=null)
	     {
	    	 k=Integer.parseInt(inputK);
	     }
	     trapDoor reDoor=paraseJsonUtil.paraseJson2Trap(searchTrapDoor, trapBitsInfo);
	     if(userName!=null&&!"".equals(userName)){
	    	 indexTreeNode root=null;
	    	 Map<String, encryptedIndex>indexMap=null;
	    	 String indexTreeKey=userName+"-"+BFConstants.INDEXTREEKEY;
	    	 String encIndex=userName+"-"+BFConstants.ENCINDEXKEY;
	    	 //首先判断缓存中是否存在索引，如果有从缓存读取，否者从hdfs中读取索引，并加到缓存中
	    	 if(cacheInstance.isContain(indexTreeKey)){
	    		 root=(indexTreeNode) cacheInstance.getCacheData(indexTreeKey);
	        	 log.info("User:"+userName+" read index tree from cacheMap");
	    	 }else{
	    		 root=hdfsOper.readIndexTree(userName+File.separator+BFConstants.SERTREENAME);
	    		 cacheInstance.addData2Cache(indexTreeKey, root);
	    		 log.info("User:"+userName+" read index tree from hdfs");
	    	 }
	    	 if(cacheInstance.isContain(encIndex)){
	    		 indexMap=(Map<String, encryptedIndex>) cacheInstance.getCacheData(encIndex);
	    		 log.info("User:"+userName+" read encrypted index  from cacheMap");
	    	 }else{
	    		 indexMap=hdfsOper.readEnIndex(userName+File.separator+BFConstants.SERINDEXNAME);
	    		 cacheInstance.addData2Cache(encIndex, indexMap);
	    		 log.info("User:"+userName+" read encrypted index  from hdfs");
	    	 }
	    	 indexTree searchIndexTree=new indexTree(root);
	    	  List<String>resultList=searchIndexTree.searchOverTree(root, reDoor.getBf());
	 	     List<fileScorePair>fileScoreList=new LinkedList<fileScorePair>();
	 	     Iterator<String>iterator=resultList.iterator();
	 	     while(iterator.hasNext())
	 	     {
	 	    	 String fileName=iterator.next();
	 	    	 encryptedIndex tempIndex=indexMap.get(fileName);
	 	    	 double tempScore=searchHelper.getScore(tempIndex, reDoor);
	 	    	 fileScorePair temPair=new fileScorePair();
	 	    	 temPair.setFileName(fileName);
	 	    	 temPair.setScore(tempScore);
	 	    	 fileScoreList.add(temPair);
	 	     }
	 	     List<String>mostKFileList=searchHelper.getMostRelateFile(fileScoreList, k);
	 	    log.info("User:"+userName+" get the most related files "+mostKFileList.toString());
	 	     JSONArray mostKFileListja=JSONArray.fromObject(mostKFileList);
	 	     PrintWriter out = null;  
	 		    try {  
	 		        out = response.getWriter();  
	 		        out.append(mostKFileListja.toString());  
	 		    } catch (IOException e) {  
	 		        e.printStackTrace();  
	 		    } finally {  
	 		        if (out != null) {  
	 		        	out.flush();
	 		            out.close();  
	 		        }  
	 		    }  
	     }
	}

}
